#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<fcntl.h>




void recv_file(int sockfd,char* name)
{
    int d_fd = open(name,O_WRONLY | __O_LARGEFILE);
    if(d_fd!=-1)//说明本地有文件，是断点续传
    {
        char d_buff[128]={0};
        if(recv(sockfd,d_buff,127,0)<=0)
        {
            return;
        }
        if(strncmp(d_buff,"ok#",3)!=0)
        {
            printf("error!!!\n");
            return;
        }
        int d_size=0;

        sscanf(d_buff+3,"%d",&d_size);
        if(d_size==0)
        {
            send(sockfd,"err",3,0);
            return;
        }
        int fd_size=lseek(d_fd,0,SEEK_END);//读取本地文件大小
        if(d_size==fd_size)
        {
            send(sockfd,"ok",2,0);
            printf("本地已经存在该文件！！！\n");
        }
        if(d_size!=fd_size)
        {
            printf("local file size:%d\n",fd_size);
            char d_res_buff[128]={0};
            sprintf(d_res_buff,"ok#size#%d",fd_size);//存在发送ok3#size#
            send(sockfd,d_res_buff,strlen(d_res_buff),0);//将本地文件大小发送到服务器
            char d_recvbuff[1024]={0};//
            double d_num=0;//
            double d_curr_size=fd_size;//从末尾接收服务器发送的文件
            float d_f;
            while((d_num=recv(sockfd,d_recvbuff,1024,0))>0)//
            {
                write(d_fd,d_recvbuff,d_num);
                d_curr_size+=d_num;
                d_f=d_curr_size*100.0/d_size;
                printf("断点续传下载进度*:%.2f%%\r",d_f);
                fflush(stdout);
                if(d_curr_size>=d_size)
                {
                    break;
                }
            }
            printf("断点续传完成\n");
        }
        close(d_fd);
        return;
    }
    else
    {
    //本地没有文件
    char buff[128]={0};
    int n=recv(sockfd,buff,127,0);
    if(strncmp(buff,"err#no name",11)==0)
    {
        printf("err no name");
    }
    if(strncmp(buff,"err",3)==0)
    {
        printf("no this file!!!\n");
        return;
    }
    int size=0;
    printf("file size:%s\n",buff+3);
    sscanf(buff+3,"%d",&size);
    if(size==0)
    {
        send(sockfd,"err",3,0);
        return;
    }
    int fd=open(name,O_WRONLY|O_CREAT,0600);
    if(fd==-1)
    {
        send(sockfd,"err",3,0);
        return;
    }
    send(sockfd,"ok",2,0);
    char recvbuff[1024]={0};
    int num=0;
    double curr_size=0;
    float t;
    while((num=recv(sockfd,recvbuff,1024,0))>0)
    {
        write(fd,recvbuff,num);
        curr_size+=num;
        t=curr_size*100.0/size;
        printf("下载进度:%.2f%%\r",t);
        fflush(stdout);
        if(curr_size>=size)
        {
            break;
        }
    }
    printf("\n文件下载完成!\n");
    close(fd);
    return;
    }
}

void send_file(int c,char *name)
{
    if(name==NULL)
    {
        send(c,"err#no",11,0);
        return;
    }
   
    int md_fd=open("md5.c",O_RDONLY|O_CREAT,0600);
    if(md_fd==-1)
    {
        printf("md_fd err\n");
        return;
    }
    char m_buff[128]={0};
    sprintf(m_buff,"./my.sh %s",name);
    system(m_buff);
    char md_res_buff[128]={0};
    read(md_fd,md_res_buff,128);
    char *s=strtok(md_res_buff,"\n");
    char buff[128]={0};
    close(md_fd);
    //system("rm md5.c");
    sprintf(buff,"ok#%s",s);
    send(c,buff,strlen(buff),0);
    char p[128]={0};
    if(recv(c,p,127,0)<=0)
    {
        return;
    }
    if(strncmp(p,"#samefile#",10)==0)
    {
        printf("秒传成功！！！\n");
        close(c);
        return;
    }
     int fd=open(name,O_RDONLY|__O_LARGEFILE);
    if(fd==-1)
    {
        send(c,"err",3,0);
        return;
    }
    int size=lseek(fd,0,SEEK_END);
    lseek(fd,0,SEEK_SET);
    if(size==0)
    {
        send(c,"err",3,0);
        return;
    }
   char res_buff[128]={0};
   sprintf(res_buff,"ok#%d",size);
   send(c,res_buff,strlen(res_buff),0);
    char cli_status[64]={0};
    if(recv(c,cli_status,63,0)<=0)
    {
        close(fd);
        return;
    }
    if(strncmp(cli_status,"ok",2)!=0)
    {
        close(fd);
        return;
    }
    double num=0;
    double curr_size=0;
    char sendbuff[1024]={0};
    float t;
    printf("文件大小：%d\n",size);
    while((num=read(fd,sendbuff,1024))>0)
    {
        printf("ddsddsdssdds");
        send(c,sendbuff,num,0);
        curr_size+=num;
        t=curr_size*100.0/size;
        printf("上传进度*:%.2f%%\r",t);
        fflush(stdout);
        if(curr_size>=size)
        {
            printf("\n文件上传完成!\n");
            break;
        }
    }
    close(fd);
    return;
}


int connect_ser()
{
    int sockfd=socket(AF_INET,SOCK_STREAM,0);
    if(sockfd==-1)
    {
        return -1;
    }
    struct sockaddr_in saddr;
    memset(&saddr,0,sizeof(saddr));
    saddr.sin_family=AF_INET;
    saddr.sin_port=htons(6000);
    saddr.sin_addr.s_addr=inet_addr("127.0.0.1");
    int res=connect(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));
    if(res==-1)
    {
        return -1;
    }
    return sockfd;
}



int main()
{
    int sockfd=connect_ser();
    if(sockfd==-1)
    {
        printf("connect to ser failed!\n");
        return 0;
    }
    while(1)
    {
        char buff[128]={0};
        printf("127.0.0.1:connect>>");
        fflush(stdout);
        fgets(buff,128,stdin);
        buff[strlen(buff)-1]=0;
        if(buff[0]==0)
        {
            continue;
        }
        char sendbuff[128]={0};
        strcpy(sendbuff,buff);//要将完整的字符串发送给服务器端，提前复制一份
        int i=0;
        char*myargv[10]={0};
        char*s=strtok(buff," ");
        while(s!=NULL)
        {
            myargv[i++]=s;
            s=strtok(NULL," ");
        }
        if(myargv[0]==NULL)
        {
            continue;
        }
        if(strcmp(myargv[0],"exit")==0)
        {
            break;
        }
        else if(strcmp(myargv[0],"get")==0)
        {
            if(myargv[1]==NULL)
            {
                continue;
            }
            send(sockfd,sendbuff,strlen(sendbuff),0);//发送get a.c到服务器
            recv_file(sockfd,myargv[1]);//接收文件
        }
        else if(strcmp(myargv[0],"rm")==0)
        {
            if(myargv[1]==NULL)
            {
                continue;
            }
            send(sockfd,sendbuff,strlen(sendbuff),0);
        }
        else if(strcmp(myargv[0],"put")==0)
        {
            if(myargv[1]==NULL)
            {
                continue;
            }
            send(sockfd,sendbuff,strlen(sendbuff),0);
            send_file(sockfd,myargv[1]);
        }
        else
        {
            send(sockfd,sendbuff,strlen(sendbuff),0);
            char readbuff[4096]={0};
            recv(sockfd,readbuff,4095,0);
            if(strncmp(readbuff,"ok#",3)!=0)
            {
                printf("err");
                continue;
            }
            printf("%s\n",readbuff+3);
        }
    }
    close(sockfd);
}
